/**
 * AutoImportGlobalBeanProcessor.java copyright xiaojian
 * Created on 2020年9月3日 上午11:09:57
 */
package xj.toolkit.registry.in;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;

import xj.toolkit.registry.GlobalBeanUtils;
import xj.toolkit.util.SimpleRegistry;

/**
 * 需要从SimpleRegistry导入bean的项目，实现AutoImportGlobalBeanProcessor的getRequiredGlobalBean方法，并且在component-scan扫描目录下。
 * 
 * @author <a href="xiaojiancao@tidalinfo.cn">xiaojian.cao</a>
 *
 */
public abstract class AbstractAutoImportGlobalBeanProcessor implements BeanDefinitionRegistryPostProcessor,BeanFactoryAware {
	
	static final Logger logger = LoggerFactory.getLogger(AbstractAutoImportGlobalBeanProcessor.class);
	
	private ConfigurableListableBeanFactory beanFactory = null;
	
	public AbstractAutoImportGlobalBeanProcessor() {}
	
	/**
	 * 得到需要从SimpleRegistry里面导出的bean的接口列表。
	 * 
	 * @return
	 */
	public abstract List<Class<?>> getRequiredGlobalBeanIntf();
	
	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		
	}

	/**
	 * 还有一种做法是使用factoryBean，输入参数为导出的bean以及关联的interface。
	 */
	@Override
	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
		SimpleRegistry sr = beanFactory.getBean(SimpleRegistry.class);
		List<Class<?>> exportEntities = getRequiredGlobalBeanIntf();
		for (Class<?> globalBeanItf : exportEntities) {
			String globalRegName = GlobalBeanUtils.getGlobalRegName(globalBeanItf);
			Object globalProxyBean = sr.getProxyOf(globalRegName, globalBeanItf);
			if (globalProxyBean == null) {
				logger.error("Cannot found globalbean with name[{}].", globalRegName);
				continue;
			}
			
			logger.debug("Register globalbean with name[{}], bean[{}].", globalRegName, globalProxyBean.getClass().getName());
			
			beanFactory.registerSingleton(globalRegName, globalProxyBean);
		}
	}

	@Override
	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
		if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
			throw new IllegalArgumentException(
					"AutowiredAnnotationBeanPostProcessor requires a ConfigurableListableBeanFactory: " + beanFactory);
		}
		this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
	
	}

}
